package com.stone.im.sdk.android;

import com.stone.im.common.Constants;
import com.stone.im.common.Request;
import com.stone.im.protobuf.proto.AuthenticateRequestProto;
import com.stone.im.protobuf.proto.MessageSendRequestProto;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;


public class ImClient {


    NioEventLoopGroup loopGroup;

    Bootstrap client;

    //代表某台机器的长连接
    private SocketChannel socketChannel;

    /**
     * 跟机器建立连接
     * @param host
     * @param post
     */
    public void connect(String host,int post) throws InterruptedException {
         this.loopGroup = new NioEventLoopGroup();

            this.client = new Bootstrap();

            client.group(loopGroup)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY,true)
                    .option(ChannelOption.SO_KEEPALIVE,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(new ImClientHandler(ImClient.this));
                            ByteBuf delimiter = Unpooled.copiedBuffer(Constants.DELIMITER);
                            socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(4096,delimiter));
                        }
                    });

            ChannelFuture channelFuture = client.connect(host, post);//尝试发起连接
            System.out.println("发起对tcp接入系统的连接....");
            channelFuture.addListener(new ChannelFutureListener() { //给异步化的请求加入监听器
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()){
                        socketChannel = (SocketChannel) channelFuture.channel();
                        System.out.println("已经跟tcp接入系统完成长连接建立，地址为："+socketChannel);
                    }else{
                        channelFuture.channel().close();
                        loopGroup.shutdownGracefully();
                    }
                }
            });
            channelFuture.sync();
    }

    public void reconnect() throws InterruptedException {
        String uid = "";
        String token ="";
        String host = null;
        int post = -1;
        connect(host,post);
        authenticate(uid,token);
    }
    /**
     * 发起用户认证
     * @param userId
     * @param token
     */
    public void authenticate(String userId,String token){
/**
 * 封装消息体
 */
        AuthenticateRequestProto.AuthenticateRequest.Builder builder = AuthenticateRequestProto.AuthenticateRequest.newBuilder();
        builder.setUid(userId);
        builder.setToken(token);
        builder.setTimestamp(System.currentTimeMillis());
        AuthenticateRequestProto.AuthenticateRequest authenticateRequest = builder.build();
        byte[] requestBytes = authenticateRequest.toByteArray();

        //封装完整的带消息头的认证请求
        Request request = new Request(Constants.APP_SDK_VERSION_1,
                Constants.SEQUENCE_DEFAULT,
                Constants.REQUEST_TYPE_AUTHENTICATE,
                requestBytes);
        System.out.println("向tcp系统发起认证,请求大小为："+authenticateRequest.toByteArray().length);

        //将认证请求发送给tcp接入系统
        socketChannel.writeAndFlush(request.getBuffer());

    }

    /**
     * 想机器发送消息
     * @param message
     * @throws Exception
     */
//    public void send(String userId,String message) throws Exception{
//
//        System.out.println("向tcp接入系统发送消息");
//        byte[] messageBytes = (message + "|" + userId + "&_").getBytes();
//        ByteBuf messagebuffer = Unpooled.buffer(messageBytes.length);
//        messagebuffer.writeBytes(messageBytes);
//
//        socketChannel.writeAndFlush(messagebuffer);
//    }

    /**
     * 关闭
     * @throws Exception
     */
    public void close() throws Exception{
        this.socketChannel.close();
        this.loopGroup.shutdownGracefully();
    }

    /**
     * 发送单挑消息
     * @param senderId
     * @param receiverId
     * @param content
     */
    public void sendMessage(String senderId,String receiverId,String content){
        MessageSendRequestProto.MessageSendRequest.Builder builder =
                MessageSendRequestProto.MessageSendRequest.newBuilder();

        builder.setContent(content);
        builder.setSenderId(senderId);
        builder.setReceiverId(receiverId);

        MessageSendRequestProto.MessageSendRequest messageSendRequest = builder.build();

        Request request = new Request(
                Constants.APP_SDK_VERSION_1,
                Constants.REQUEST_TYPE_SEND_MESSAGE,
                Constants.SEQUENCE_DEFAULT,
                messageSendRequest.toByteArray()
        );
        System.out.println("客户端向接入系统发送一条单聊消息");
        socketChannel.writeAndFlush(request.getBuffer());
    }

}
